package com.instpower.things.instpower;

import com.instpower.things.service.InstService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName DeviceSessionManager
 * @Author: hellmash@gmail.com
 * @Date: 2020/3/19
 * @Version: 1.0.0
 * @Description: 连接会话管理
 */
public class DeviceSessionManager {

    private final Map<String, DeviceSession> mSessions;
    private static DeviceSessionManager mInstance;

    private final InstService instService = Context.getBean("instService");

    private final RedisTemplate redisTemplate = Context.getBean(RedisTemplate.class);

    private final Logger logger = LoggerFactory.getLogger("CORE");

    private DeviceSessionManager() {
        mSessions = new ConcurrentHashMap<>();
    }

    public static DeviceSessionManager getInstance() {
        if (mInstance == null) {
            mInstance = new DeviceSessionManager();
        }
        return mInstance;
    }

    public void add(final DeviceSession session) {
        //如果session中存在同样的终端,说明之前的连接已经无效,先断开原来的连接
        String cabinetSn = session.getCabinetSn();
        if (mSessions.containsKey(cabinetSn)) {
            Connection connection = mSessions.get(cabinetSn).getMConnection();
            if (null != connection) {
                connection.close();
                logger.debug("SN:{} cabinet offline, connect:{} close  ,doOnclose() " ,cabinetSn,connection.getId());
            }
            mSessions.remove(cabinetSn);
        }
        mSessions.put(cabinetSn, session);
        session.getMConnection().registerCloseListener(conn -> {
            mSessions.remove(cabinetSn);
            redisTemplate.delete(cabinetSn);
            instService.updateCabinetOffline(cabinetSn);
            logger.debug("SN:{} cabinet offline. Cabinet re-login", cabinetSn);
        });
    }

    public DeviceSession get(String cabinetSn) {
        return mSessions.get(cabinetSn);
    }

    public Map<String, DeviceSession> sessions() {
        return mSessions;
    }
}

